﻿
using System.Collections.Generic;

namespace LxCFD
{
    public class RANSkwUnit : LinearSolver, ISolvableUnit, ITurbulentSolvable// TurbulenceUnitBase
    {
        public List<TurbulenceModelkw> kws = new List<TurbulenceModelkw>();
        public List<NSEquation> ks = new List<NSEquation>();
        public List<NSEquation> ws = new List<NSEquation>();
        public List<ConnectWallBase> connects = new List<ConnectWallBase>();//暂时不用，占位
        public void Initialize(List<TurbulenceModelkw> kws, List<ConnectWallBase> connects)
        {
            this.kws = kws;
            this.connects = connects;
            SetAMGSolver(kws, connects);
        }

        public  void UpdateGammaForMomentum(int taskIndex)
        {
            foreach (var com in kws) { com.Cal_MomGamma(taskIndex); }
        }
        public  void UpdateGammaForTemperature(int taskIndex)
        {
            foreach (var com in kws) { com.Cal_TemperatureGamma(taskIndex); }
        }
        public  void Solve_Steady()
        {
            //k
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_kGamma(taskIndex); }
            });
            prepareMatrix(ks);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Add_k_Ab_byConstitutiveEquation(taskIndex); }
            });
            RelaxAndSolve(ks, connects);
            updateBoundAndLimit(ks);
            //w
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_wGamma(taskIndex); }
            });
            prepareMatrix(ws);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(taskIndex); }
            });
            RelaxAndSolve(ws, connects);
            updateBoundAndLimit(ws);
        }
        protected void prepareMatrix(List<NSEquation> kews)
        {
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kews) { com.CalGradient(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kews) { com.SetAb_Step1(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kews) { com.SetAb_Step2(taskIndex); }
            });
        }
        protected void updateBoundAndLimit(List<NSEquation> kews)
        {
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kews) { com.Update_x_Bound(taskIndex); }
            });
            foreach (var com in kews) { com.Limit_x(); }
        }
        public  void Solve_ImplicitTransient()
        {
            //k
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_kGamma(taskIndex); }
            });
            prepareMatrix(ks);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in ks) { com.TransData.SetAb_ImplicitTrans(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Add_k_Ab_byConstitutiveEquation(taskIndex); }
            });
            RelaxAndSolve(ks, connects);
            updateBoundAndLimit(ks);
            //w
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_wGamma(taskIndex); }
            });
            prepareMatrix(ws);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in ws) { com.TransData.SetAb_ImplicitTrans(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(taskIndex); }
            });
            RelaxAndSolve(ws, connects);
            updateBoundAndLimit(ws);
        }
        public  void Solve_ExplicitTransient()
        {
            //k
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_kGamma(taskIndex); }
            });
            prepareMatrix(ks);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in ks) { com.TransData.SetAb_ExplicitTrans(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Add_k_Ab_byConstitutiveEquation(taskIndex); }
            });
            SolveExplicit(ks, connects);
            updateBoundAndLimit(ks);
            //w
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Cal_wGamma(taskIndex); }
            });
            prepareMatrix(ws);
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in ws) { com.TransData.SetAb_ExplicitTrans(taskIndex); }
            });
            MultiThreads.RunCalTasks((taskIndex) =>
            {
                foreach (var com in kws) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(taskIndex); }
            });
            SolveExplicit(ws, connects);
            updateBoundAndLimit(ws);
        }

        public void SaveOldValue()
        {
            throw new System.NotImplementedException();
        }
    }
}
//public void Addkew(TurbulenceModelkw kew)
//{
//    kws.Add(kew);
//    ks.Add(kew.k);
//    ws.Add(kew.w);
//}
//public RANSkwUnit kwStor { get; set; }
//public override void Clear()
//{
//    base.Clear();
//    kwStor = new RANSkwUnit();
//}